from django.db import transaction
from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from ..utils.response_utils import api_response, ResponseCode
from .models import Asset
from .serializers import AssetSerializer, UpdateAssetSerializer, SaveAssetSerializer, \
    BulkCreateAssetSerializer
import os
import uuid
from django.core.files.storage import default_storage
from django.core.exceptions import ObjectDoesNotExist


class ListAssetView(APIView):
    """
    列表资源接口
    """

    @swagger_auto_schema(
        operation_description="获取资源列表",
        responses={
            200: AssetSerializer(many=True),
            500: "服务器错误"
        },
        tags=["资源管理"]
    )
    def get(self, request):
        try:
            # 根据实际需求可添加过滤逻辑，如根据 project 或 type 筛选
            assets = Asset.objects.all().order_by('-project', '-created_at')
            serializer = AssetSerializer(assets, many=True)
            return api_response(ResponseCode.SUCCESS, "获取成功", serializer.data)
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, str(e))


class CreateAssetView(APIView):
    """
    创建资源接口
    """
    parser_classes = [JSONParser]  # 改为JSON解析

    @swagger_auto_schema(
        operation_description="批量上传资源",
        request_body=BulkCreateAssetSerializer(many=True),
        responses={
            200: AssetSerializer(many=True),
            400: openapi.Response(description="参数错误"),
            500: "服务器错误"
        },
        tags=["资源管理"]
    )
    def post(self, request):
        try:
            with transaction.atomic():
                serializer = BulkCreateAssetSerializer(data=request.data, many=True, context={'request': request})

                if not serializer.is_valid():
                    return api_response(ResponseCode.BAD_REQUEST, f"参数错误：{serializer.errors}")

                instances = serializer.save()
                result_serializer = AssetSerializer(instances, many=True)
                return api_response(ResponseCode.SUCCESS, f"成功创建 {len(instances)} 个资源", result_serializer.data)
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, str(e))


class UpdateAssetView(APIView):
    """
    更新资源接口
    """
    parser_classes = [MultiPartParser, FormParser]

    @swagger_auto_schema(
        operation_description="更新资源信息",
        manual_parameters=[
            openapi.Parameter('asset_id', openapi.IN_PATH, type=openapi.TYPE_STRING),
            openapi.Parameter(
                name='file',
                in_=openapi.IN_FORM,
                type=openapi.TYPE_FILE,
                description='更新资源文件',
                required=False
            )
        ],
        request_body=UpdateAssetSerializer,
        responses={
            200: AssetSerializer,
            400: "参数错误",
            404: "资源不存在",
            500: "服务器错误"
        },
        tags=["资源管理"]
    )
    def put(self, request, asset_id):
        try:
            asset = Asset.objects.get(id=asset_id)
            uploaded_file = request.FILES.get('file')

            # 如果有文件上传，则按创建接口逻辑进行文件相关验证和保存
            if uploaded_file:
                # 文件类型验证
                allowed_mime_types = ['image/jpeg', 'image/png', 'font/ttf', 'font/woff']
                if uploaded_file.content_type not in allowed_mime_types:
                    return api_response(ResponseCode.BAD_REQUEST, "不支持的文件类型")
                # 文件大小限制（5MB）
                if uploaded_file.size > 5 * 1024 * 1024:
                    return api_response(ResponseCode.BAD_REQUEST, "文件大小超过5MB")
                # 删除旧文件（如果存在）
                if default_storage.exists(asset.url):
                    default_storage.delete(asset.url)
                file_ext = os.path.splitext(uploaded_file.name)[1]
                # 根据请求中提供的 type 字段（如果未传，则沿用原有类型）决定文件存储目录
                file_type = request.data.get('type', asset.type)
                if file_type == 'background':
                    new_filename = f"assets/background/{uuid.uuid4()}{file_ext}"
                elif file_type == 'mask':
                    new_filename = f"assets/mask/{uuid.uuid4()}{file_ext}"
                elif file_type == 'font':
                    new_filename = f"assets/font/{uuid.uuid4()}{file_ext}"
                else:
                    return api_response(ResponseCode.BAD_REQUEST, "不支持的资源类型")
                file_path = default_storage.save(new_filename, uploaded_file)
                # 更新文件相关字段
                asset.url = file_path
                asset.original_filename = uploaded_file.name
                asset.file_size = uploaded_file.size
                asset.mime_type = uploaded_file.content_type
                asset.thumbnail_url = file_path
                asset.optimized_url = file_path

            # 更新其他字段（如 type、图片尺寸、缩略图、优化后的 URL 等）
            serializer = SaveAssetSerializer(asset, data=request.data, partial=True)
            if serializer.is_valid():
                serializer.save()
                # 返回完整的资源信息
                output_serializer = AssetSerializer(asset)
                return api_response(ResponseCode.SUCCESS, "更新成功", output_serializer.data)
            return api_response(ResponseCode.BAD_REQUEST, f"参数错误：{serializer.errors}")
        except ObjectDoesNotExist:
            return api_response(ResponseCode.NOT_FOUND, "资源不存在")
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, str(e))


class DeleteAssetView(APIView):
    """
    删除资源接口
    """

    @swagger_auto_schema(
        operation_description="删除资源",
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            required=['asset_ids'],
            properties={
                'asset_ids': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Schema(type=openapi.TYPE_STRING),
                                            description="资源ID"),
            }
        ),
        responses={
            200: "删除成功",
            404: "资源不存在",
            500: "服务器错误"
        },
        tags=["资源管理"]
    )
    def delete(self, request):
        asset_ids = request.data.get('asset_ids', [])
        if not asset_ids and not isinstance(asset_ids, list):
            return api_response(ResponseCode.BAD_REQUEST, "参数错误")
        not_found_ids = []
        try:
            for asset_id in asset_ids:
                try:
                    asset = Asset.objects.get(id=asset_id)
                    # 删除关联文件
                    if default_storage.exists(asset.url):
                        default_storage.delete(asset.url)
                    asset.delete()
                except ObjectDoesNotExist:
                    not_found_ids.append(asset_id)
            if not_found_ids:
                return api_response(ResponseCode.NOT_FOUND,
                                    f"成功删除资源{len(asset_ids) - len(not_found_ids)}个，未找到资源：{len(not_found_ids)}个")
            return api_response(ResponseCode.SUCCESS, "删除成功")
        except Exception as e:
            return api_response(ResponseCode.INTERNAL_SERVER_ERROR, str(e))
